
// 可以先考虑扩展性，先满足自身
// 一个组件的权限肯定有一个最还曾的

import React from "react";
import type {ComponentType} from 'react'
import {Tooltip} from 'antd';

type AuthCode = string;

export type AuthWrapperProps = {
  children: JSX.Element;
  authCode?:string;
  alwaysRender?:boolean;
}


// 按钮级权限的权限设计方案，后端是怎么存储select的option

/**
 * 全局方法
 * @param authCode
 * @returns
 */
export function isAuth(authCode:AuthCode){
  const permissionList = ['home.detail.edit', 'some.other.permission'];
  return permissionList.includes(authCode);
}

const useAuth = (authCode?:string)=>{
  if(!authCode){
    return true
  }
  const permissionList = ['home.detail.edit', 'some.other.permission','list.face.on'];
  // ....useHook、useContext去获取permisssionList；
  const hasAuth = permissionList.includes(authCode)
  return hasAuth
}


/**
 * 权限控制高阶组件,对于单个组件进行封装
 * @param authCode
 * @param alwaysRender
 * @returns
 * example:
 * withAuth(Button)('home.detail.edit') 一个没权限也始终显示的Button
 * withAuth('home.detail.edit',false)(Button) 一个没权限即隐藏的Button
 * Component:T extends React.ComponentType
*/




interface AuthOptionsType {
  alwaysRender?: boolean;
  showTooltip?: boolean;
  tooltipText?: string;
}

interface AuthCompProps {
  authCode?: string;
  [key: string]: any; // 允许其他附加属性
}



/**
 * 权限控制高阶组件
 * @param Component
 * @returns 新的权限组件，仍然保持原组件的功能
 *
 */
export function withAuth<P>(Component:ComponentType<P>) {  //P表示组件的props类型

  return function({alwaysRender=true,showTooltip=true,tooltipText='无操作权限'}:AuthOptionsType){
    const AuthComp:React.FC<AuthCompProps & P> = ({ authCode, ...props }) => {
      const hasAuth = useAuth(authCode)
      const show = hasAuth || alwaysRender
      console.log('AuthCode:', authCode);
      console.log('Props:', props);

      if(!show) return null;
      let newComp = <Component  {...(props as P)} disabled={!hasAuth}/>
      if(showTooltip){
        newComp = (
          <Tooltip title={tooltipText}>
            {newComp}
          </Tooltip>
        )
      }

      return newComp
    };
    // 设置 displayName 以便于调试
    console.log('Rendering component:', Component.displayName || Component.name || 'Component');


    return AuthComp;
  }

}



/**,
 * 权限容器
 * @param param
 * @returns
 */
export const AuthWrapper = ({children,authCode,alwaysRender=true,}:AuthWrapperProps)=>{
  if(!authCode) return children;
  const hasAuth = useAuth(authCode);
  const show = alwaysRender || hasAuth;
  console.log('disabled',!hasAuth)

  if(show){
    let Comp = React.cloneElement(children,{disabled:!hasAuth})
    if(!hasAuth){
      Comp = (
        <Tooltip title="无操作权限">
          {Comp}
        </Tooltip>
      )
    }
    return Comp
  }
  else{
    return null
  }
}


//这种写法只能是对children写法把？
const renderAuthBanButton: (children: any) => any = children => {
  return React.Children.map(children, child => {
    if (['boolean', 'undefined', 'string', 'number'].includes(typeof child) || child === null) {
      return child;
    }
    if (child.props.children) {
      return React.cloneElement(
        child,
        {
          onClick: e => {
            e.preventDefault();
            return false;
          },
          className: 'ant-btn-disabled'
        },
        renderAuthBanButton(child.props.children)
      );
    }
    return React.cloneElement(child, {
      onClick: e => {
        e.preventDefault();
        return false;
      },
      className: 'ant-btn-disabled'
    });
  });
};

// 作者：zlevai
// 链接：https://juejin.cn/post/7097062343309918238
// 来源：稀土掘金
// 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。
